/******************************************************************************/
/*! 
    Filename
    [Copyright]

    \file
    \namespace    
    \brief      
*/
/******************************************************************************/
/*** Includes *****************************************************************/
#include "NAttributed.h"
#include <assert.h>

/*** Using ********************************************************************/
using namespace Core;

/*** Macros *******************************************************************/
RTTI_DEFINITIONS(NAttributed)

/*** Constants ****************************************************************/

/*** Declarations *************************************************************/

/*** Variables ****************************************************************/

/*** Implementation ***********************************************************/
/******************************************************************************/
/*! NAttributed :: Constructor

    \brief  Default Ctor
    \param  -void
    \return -void
*/
/******************************************************************************/
NAttributed::NAttributed(void)
	:NScope()
{
}
/******************************************************************************/
/*! NAttributed :: Copy Constructor

    \brief  Copy Ctor
    \param  rhs - source of data 
    \return -void
*/
/******************************************************************************/
NAttributed::NAttributed(const NAttributed & rhs)
	: NScope(rhs)
{	
	*this = rhs;	
}
/******************************************************************************/
/*! NAttributed :: Deconstructor

    \brief  Dtor

    \param  -void
    \return -void
*/
/******************************************************************************/
NAttributed::~NAttributed(void)
{
	Clear();
}
/******************************************************************************/
/*! NAttributed :: Assignment Operator

    \brief  Assignment Operator

    \param  rhs - source of information
    \return NAttributed & - reference to object
*/
/******************************************************************************/
NAttributed& NAttributed::operator = (const NAttributed & rhs)
{
	if(*this != rhs)
	{
		Clear();
		NScope::operator = (rhs);
		mSignatures = rhs.mSignatures;
	}
	return *this;	
}
/******************************************************************************/
/*! NAttributed :: [Function]

    \brief  

    \param  
    \return
*/
/******************************************************************************/
void NAttributed::Populate()
{
	if(mSignatures.size() == 0)
	{
		mSignatures.reserve(1);
		return;
	}
	
	NDatum& selfDatum  = Append("This");//add self to scope
	if(!selfDatum.isExternal() && selfDatum.GetType() != NDatum::eTYPE_UNKNOWN)
	{
		selfDatum.Clear();
	}
	selfDatum.SetStorage(this,1,1);

	Signatures::iterator vectorIt = mSignatures.begin();//go throw vector and add

	NDatum * newDatum;
	for(;vectorIt != mSignatures.end();vectorIt++)				//walk signature array and append to table
	{
		newDatum = &Append((*vectorIt).Name);						//get datum paired with name	
		if(newDatum->GetType() == NDatum::eTYPE_UNKNOWN)
		{
			if((*vectorIt).Storage != 0)
			{
				newDatum->SetStorage  ((*vectorIt).Storage, (*vectorIt).NumberElements, (*vectorIt).NumberElements);
			}

			newDatum->SetType	  (	(*vectorIt).Type , true	);
			newDatum->SetNumValues(	(*vectorIt).NumberElements	);
			
			for(unsigned int i = 0; i < (*vectorIt).NumberElements;i++) //populate datum with init value
			{
				Signature aSignature = (*vectorIt);
				switch(newDatum->GetType())
				{
					case NDatum::eTYPE_INT:
						if(aSignature.Storage != 0)
						{
							int* values = (int*)aSignature.Storage;
							newDatum->Set(values[i],i);
						}
						else
						{
							int* value = (int*) aSignature.InitValue;
							newDatum->Set(*value,i);
						}
					break;
					case NDatum::eTYPE_FLOAT:
						if(aSignature.InitValue == 0 )
						{
							newDatum->Set(0.0f,i);
						}
						else
						{
							newDatum->Set(*static_cast<float*>(aSignature.InitValue),i);
						}		
					break;
					case NDatum::eTYPE_STRING:
						if(aSignature.InitValue == 0)
						{
							std::string* value = (std::string*)aSignature.Storage;
							if(value != NULL)
							{
								newDatum->Set(value[i],i);
							}
						}
						else
						{
							newDatum->Set((char *)aSignature.InitValue, i);
						}
					break;
					case NDatum::eTYPE_MATRIX:
						if(aSignature.InitValue == 0)
						{
							//newDatum->Set(Matrix3(),i);
						}
						else
						{
							//newDatum->Set(*static_cast<Matrix3*>(aSignature.InitValue), i);
						}
					break;
					case NDatum::eTYPE_VECTOR:
						if(aSignature.InitValue == 0)
						{
							//newDatum->Set(Vector3(), i);
						}
						else
						{
							//newDatum->Set(*static_cast<Vector3*>(aSignature.InitValue), i);
						}
					break;

					case NDatum::eTYPE_SCOPE:
						if(aSignature.InitValue == 0)
						{
							newDatum->Set(NULL, i);
						}
						else
						{
							newDatum->Set(static_cast<NScope*>(aSignature.InitValue), i);
						}

					break;

					default:
						assert(false);
					break;
				}
			}
		}
	}
}
/******************************************************************************/
/*! NAttributed :: [Function]

    \brief  

    \param  
    \return
*/
/******************************************************************************/
bool NAttributed::IsPrescribedAttribute(const char* attributeName) const
{
	unsigned int index = Index_Find(attributeName);
	if(index > 0 && index < mSignatures.size()+1)
	{	
		return true;	
	}
	return false;
}
/******************************************************************************/
/*! NAttributed :: [Function]

    \brief  

    \param  
    \return
*/
/******************************************************************************/
bool NAttributed::IsAuxilliaryAttribute(const char*  auxilliaryName) const
{
	if(!IsPrescribedAttribute(auxilliaryName) && isAttribute(auxilliaryName))
	{	
		return true;	
	}
	return false;
}
/******************************************************************************/
/*! NAttributed :: [Function]

    \brief  

    \param  
    \return
*/
/******************************************************************************/
bool NAttributed::isAttribute(const char*  attributeName) const
{
	return Search(attributeName);
}
/******************************************************************************/
/*! NAttributed :: [Function]

    \brief  

    \param  
    \return
*/
/******************************************************************************/
NDatum & NAttributed::AppendAuxiliaryAttribute(const char*  attributeName)
{
	return Append(attributeName);
}
/******************************************************************************/
/*! NAttributed :: [Function]

    \brief  

    \param  
    \return
*/
/******************************************************************************/
unsigned int NAttributed::AuxBegin() const
{
	return mSignatures.size();
}
/******************************************************************************/
/*! NAttributed :: [Function]

    \brief  

    \param  
    \return
*/
/******************************************************************************/
void NAttributed::Clear()
{
	mSignatures.clear();
}
